package cn.z2huo.mybatis.generator.mybatisplus.plugin;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;

import java.util.List;

/**
 * <p>生成对象插件类
 *
 * <p>生成类注释和字段注释，以及需要使用额注解和 import
 *
 * @author z2huo
 */
public class ModelGeneratorPlugin extends PluginAdapter {

    /**
     * <p>基类中应该具有的字段
     * <p>包括：创建时间、创建人、更新时间、更新人
     */
    private static final List<String> BASE_DO_FIELD_NAME_LIST = List.of("createTime", "operateTime", "createByCode", "operateByCode");

    private static final List<String> CREATE_FIELD_NAME_LIST = List.of("createTime", "createByCode");

    public static final List<String> OPERATE_FIELD_NAME_LIST = List.of("operateTime", "operateByCode");

    public static final String ID_KEY = "id";

    /**
     * <p>生成的DO实体对象的类型，用于 MyBatis-plus BaseMapper 泛型
     */
    private FullyQualifiedJavaType doModelJavaType;

    @Override
    public boolean validate(List<String> list) {
        return true;
    }

    /**
     * <p>自定义生成的实体类
     */
    @Override
    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {

        // import
        // lombok import
        topLevelClass.addImportedType("lombok.Data");
        topLevelClass.addImportedType("lombok.NoArgsConstructor");
        topLevelClass.addImportedType("lombok.experimental.Accessors");
        // mybatis-plus import
        topLevelClass.addImportedType("com.baomidou.mybatisplus.annotation.TableName");

        // 注解
        // lombok 注解
        topLevelClass.addAnnotation("@Data");
        topLevelClass.addAnnotation("@NoArgsConstructor");
        topLevelClass.addAnnotation("@Accessors(chain = true)");
        // Mybatis-plus表注解
        topLevelClass.addAnnotation(String.format("@TableName(\"%s\")", introspectedTable.getFullyQualifiedTable().getIntrospectedTableName()));

        doModelJavaType = topLevelClass.getType();

        return true;
    }

    /**
     * <p>自定义生成的实体类属性
     */
    @Override
    public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn,
                                       IntrospectedTable introspectedTable, ModelClassType modelClassType) {

        if (BASE_DO_FIELD_NAME_LIST.contains(field.getName())) {
            topLevelClass.addImportedType("com.baomidou.mybatisplus.annotation.FieldFill");
            topLevelClass.addImportedType("com.baomidou.mybatisplus.annotation.TableField");
        }

        if (introspectedTable.hasPrimaryKeyColumns()) {
            topLevelClass.addImportedType("com.baomidou.mybatisplus.annotation.IdType");
            topLevelClass.addImportedType("com.baomidou.mybatisplus.annotation.TableId");

            if (introspectedTable.getPrimaryKeyColumns().size() == 1) {
                if (ID_KEY.equals(introspectedTable.getPrimaryKeyColumns().getFirst().getActualColumnName())
                        && ID_KEY.equals(introspectedColumn.getActualColumnName())) {
                    field.addAnnotation("@TableId(type = IdType.ASSIGN_ID)");
                }
            } else if (introspectedTable.getPrimaryKeyColumns().size() > 1){
                if (introspectedTable.getPrimaryKeyColumns().contains(introspectedColumn)) {
                    field.addAnnotation("@TableId(type = IdType.INPUT)");
                }
            }
        }

        if (CREATE_FIELD_NAME_LIST.contains(field.getName())) {
            field.addAnnotation("@TableField(fill = FieldFill.INSERT)");
        } else if (OPERATE_FIELD_NAME_LIST.contains(field.getName())) {
            field.addAnnotation("@TableField(fill = FieldFill.INSERT_UPDATE)");
        }

        return true;
    }

    /**
     * <p>实体类对象不生成 Setter
     */
    @Override
    public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        return false;
    }

    /**
     * <p>实体类对象不生成 Getter
     */
    @Override
    public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        return false;
    }

    /**
     * <p>自定义生成的 DAO 接口
     */
    @Override
    public boolean clientGenerated(Interface interfaze, IntrospectedTable introspectedTable) {

        // 添加 spring 注解
        interfaze.addImportedType(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Mapper"));
        interfaze.addAnnotation("@Mapper");

        // 添加 mybatis-plus
        FullyQualifiedJavaType baseMapperJavaType = new FullyQualifiedJavaType("com.baomidou.mybatisplus.core.mapper.BaseMapper");
        baseMapperJavaType.addTypeArgument(doModelJavaType);

        interfaze.addImportedType(baseMapperJavaType);
        interfaze.addSuperInterface(baseMapperJavaType);

        return true;
    }

    /**
     * 不生成 example 对象
     */
    @Override
    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

}
